using System;
using NUnit.Framework;

namespace NAsserter.Tests
{
    public class Asserter_IsNotNull : AssertionHelper
    {
        [Test]
        public void with_non_null_object()
        {
            var entity = new TestEntity();

            AssertThat.Argument(entity, "entity").IsNotNull();
        }

        [Test]
        public void with_non_null_value_type()
        {
            AssertThat.Argument(23, "age").IsNotNull();
        }

        [Test]
        public void with_non_null_nullable_value_type()
        {
            AssertThat
                .Argument((int?)23, "age").IsNotNull()
                    .Exists(1, 2, 3)
                .Argument(new TestEntity { Amount = 200, Parent = null }, "entity")
                    .IsNotNull()
                    .If(true)
                        .IsNotNull()
                    .Property(x => x.Parent, "Parent")
                        .Assertions(x => x.IsNotNull());
        }

        [Test]
        public void with_null_nullable_value_type()
        {
            Expect(
                () => AssertThat.Argument((int?) null, "age").IsNotNull(),
                Throws.TypeOf<ArgumentNullException>());
        }

        [Test]
        public void with_non_null_object_with_non_null_property()
        {
            var obj = new TestEntity {Amount = 100, Id = 3, Parent = new TestEntity()};

            AssertThat.Argument(obj, "obj")
                .IsNotNull()
                    .Property(x => x.Parent, "Parent")
                        .Assertions(x => x.IsNotNull());
        }

        [Test]
        public void with_non_null_object_with_null_property()
        {
            var obj = new TestEntity { Amount = 100, Id = 3, Parent = null };

            Expect(
                () => AssertThat.Argument(obj, "obj")
                        .IsNotNull()
                        .Property(x => x.Parent, "Parent")
                            .Assertions(x => x.IsNotNull()),
                Throws.TypeOf<ArgumentNullException>());
        }

        [Test]
        public void with_null_object_and_exception_with_description()
        {
            Expect(
                () => AssertThat
                    .Argument((TestEntity)null, "entity").IsNotNull(),
                Throws
                    .TypeOf<ArgumentNullException>().With
                        .Message.Contains("entity"));
        }

        [Test]
        public void with_null_object_and_exception_with_name()
        {
            Expect(
                () => AssertThat
                    .Argument((TestEntity)null, "entity").IsNotNull(),
                Throws
                    .TypeOf<ArgumentNullException>().With
                        .Property("ParamName").Contains("entity"));
        }

        [Test]
        public void with_null_object_and_exception_with_name_and_description()
        {
            Expect(
                () => AssertThat
                    .Argument((TestEntity) null, "entity").IsNotNull(),
                Throws
                    .TypeOf<ArgumentNullException>().With
                        .Message.Contains("entity").And
                        .Property("ParamName").Contains("entity"));
        }
    }
}